#pragma once

#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>

#include "Shader.h"
#include "FramebufferObject.h"
#include "RenderbufferObject.h"
#include "Texture.h"

class PushAttribute
{
public:
	PushAttribute(GLbitfield mask);
	~PushAttribute(void);
};

class PushMatrix
{
public:
	PushMatrix(GLenum mode);
	~PushMatrix(void);
};

class PushDrawCall
{
public:
	PushDrawCall(GLenum mode);
	~PushDrawCall(void);
};

class PushQuery
{
public:
	PushQuery(GLuint id);
	~PushQuery(void);
};

class PushShader
{
public:
	PushShader(const Shader& shader);
	~PushShader(void);
private:
	const Shader& _shader;
	PushShader& operator=(const PushShader&) {}
};

class PushFBOAttachment
{
public:
	PushFBOAttachment(FramebufferObject& FBO, const GLenum attachment, const Texture& texture);
	PushFBOAttachment(FramebufferObject& FBO, const GLenum attachment, const Texture& texture, const int layer);
	PushFBOAttachment(FramebufferObject& FBO, const GLenum attachment, const RenderbufferObject& RBO);
	~PushFBOAttachment(void);
protected:
	PushFBOAttachment(FramebufferObject& FBO, const GLenum attachment);
	FramebufferObject& _FBO;
	const GLenum _attachment;
private:
	PushFBOAttachment& operator=(const PushFBOAttachment&) {}
};

class PushFBOAttachment2DRW : PushFBOAttachment
{
public:
	PushFBOAttachment2DRW(FramebufferObject& FBO, const GLenum attachment, const Texture2DRW& texture);
	~PushFBOAttachment2DRW(void);
private:
	PushFBOAttachment2DRW& operator=(const PushFBOAttachment2DRW&) {}
};

class PushFBOAttachmentRectRW : PushFBOAttachment
{
public:
	PushFBOAttachmentRectRW(FramebufferObject& FBO, const GLenum attachment, const TextureRectRW& texture);
	~PushFBOAttachmentRectRW(void);
private:
	PushFBOAttachmentRectRW& operator=(const PushFBOAttachmentRectRW&) {}
};
